﻿using AutoMapper;
using HamcoWcs.Contract.ContractCommon;
using HamcoWcs.Contract.ContractMes;
using HamcoWcs.Contract.ContractPcon;
using HamcoWcs.Contract.ContractSrm;
using HamcoWcs.DAL;
using HamcoWcs.Entitys.MesMsgQueues;
using HamcoWcs.Entitys.WcsLocations;
using HamcoWcs.Models.Common.Enums;
using HamcoWcs.Models.TibcoMessage;
using HamcoWcs.Service.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Xml;

namespace HamcoWcs.Service.Mes.Parsers
{
    /// <summary>
    /// MES获取托盘信息
    /// </summary>
    public class MesMsgParser_GetInventoryPalletDataRequest : MesMsgParserBase
    {
        public override void HandleEvent(MesMsgQueue message)
        {
            var res = message.Content;
            var machineName = XmlHelper.GetXPathText(res, "//MACHINENAME");
            var positionType = XmlHelper.GetXPathText(res, "//CURRENTPOSITIONTYPE");
            var zoneName = XmlHelper.GetXPathText(res, "//CURRENTZONENAME");
            var portName = XmlHelper.GetXPathText(res, "//CURRENTPOSITIONNAME");
            res = XmlHelper.SetXmlNodeText(res, "MESSAGENAME", "GetInventoryPalletDataReply");
            res = XmlHelper.SetXmlNodeText(res, "REPLYSUBJECTNAME", TibcoConfiguration.BasicConfiguration.RecvSubject);
            try
            {
                if (string.IsNullOrEmpty(machineName))
                    throw new MESJobException(101, "Error MachineName");
                if (string.IsNullOrEmpty(positionType))
                    throw new MESJobException(102, "Error CurrentPositionType");

                var doc = new XmlDocument();
                doc.LoadXml(res);
                var pallets = doc.SelectSingleNode("//PALLETLIST");
                if (pallets is null)
                {
                    pallets = doc.CreateElement("PALLETLIST");
                }
                pallets.RemoveAll();

                if (positionType == "SHELF")
                {
                    var locs = new List<WcsLocation>();
                    if (!string.IsNullOrEmpty(zoneName))
                    {
                        if (!zoneName.IsZone())
                            throw new MESJobException(104, "ZoneName is not correct pattern");

                        locs = _wcsDbContext.WcsLocations
                            .Where(x => x.LocType == "shelf")
                            .Where(x => x.ZoneName == zoneName)
                            .Where(x => !string.IsNullOrEmpty(x.UnitId))
                            .ToList();
                    }
                    else
                    {

                        var zonePallets = _locationService.InventoryPalletsByZone();

                        foreach (var z in zonePallets.Keys)
                        {
                            if (z.Contains(machineName))
                            {
                                var mm = new InventoryPalletDataReportMessage(
                                    new InventoryPalletDataReportMessageBody(z.Substring(0, 8), zonePallets[z]));

                                mm.HEADER.MESSAGENAME = "InventoryPalletDataReport";
                                _mesCommunicateService.InventoryPalletDataReport(mm);
                                Thread.Sleep(100);
                            }
                        }
                        message.Status = (int)EnumMesMsgStatus.WcsExcuted;
                        message.Return = XmlHelper.XmlDocumentToString(doc);
                        return;
                    }

                    foreach (var loc in locs)
                    {
                        var pallet = doc.CreateElement("PALLET");
                        var PALLETNAME = doc.CreateElement("PALLETNAME");
                        var PALLETLOCSTATE = doc.CreateElement("PALLETLOCSTATE");
                        var TRANSFERSTATE = doc.CreateElement("TRANSFERSTATE");
                        var CURRENTPOSITIONNAME = doc.CreateElement("CURRENTPOSITIONNAME");
                        PALLETNAME.InnerText = loc.UnitId;
                        PALLETLOCSTATE.InnerText = (loc.IsLock && loc.SrmOccupyFlag) ? "BLOCKED" : "UNBLOCKED";
                        TRANSFERSTATE.InnerText = "INSTK";
                        CURRENTPOSITIONNAME.InnerText = loc.WcsLocName;
                        pallet.AppendChild(PALLETNAME);
                        pallet.AppendChild(PALLETLOCSTATE);
                        pallet.AppendChild(TRANSFERSTATE);
                        pallet.AppendChild(CURRENTPOSITIONNAME);
                        pallets.AppendChild(pallet);
                    }


                }
                else if (positionType == "PORT")
                {
                    if (string.IsNullOrEmpty(portName))
                        throw new MESJobException(105, "Error PortName");

                    var dev = _asrs.Nodes.FirstOrDefault(x => x.NodeName == machineName)
                        ?? throw new MESJobException(106, $"Not found target machine:{machineName}");

                    var p = dev.Pcons.FirstOrDefault(x => x.PortName == portName)
                        ?? throw new MESJobException(107, $"Not found target port:{portName}");

                    if (!string.IsNullOrEmpty(p.UnitId))
                    {
                        var pallet = doc.CreateElement("PALLET");
                        var PALLETNAME = doc.CreateElement("PALLETNAME");
                        var PALLETLOCSTATE = doc.CreateElement("PALLETLOCSTATE");
                        var TRANSFERSTATE = doc.CreateElement("TRANSFERSTATE");
                        var CURRENTPOSITIONNAME = doc.CreateElement("CURRENTPOSITIONNAME");
                        PALLETNAME.InnerText = p.UnitId;
                        PALLETLOCSTATE.InnerText = "UNBLOCKED";
                        TRANSFERSTATE.InnerText = "MOVING";
                        CURRENTPOSITIONNAME.InnerText = portName;

                        pallet.AppendChild(PALLETNAME);
                        pallet.AppendChild(PALLETLOCSTATE);
                        pallet.AppendChild(TRANSFERSTATE);
                        pallet.AppendChild(CURRENTPOSITIONNAME);
                        pallets.AppendChild(pallet);
                    }
                }
                else
                {
                    throw new MESJobException(103, $"Not define CurrentPositionType:{positionType}");
                }

                var body = doc.SelectSingleNode("//BODY");
                body.AppendChild(pallets);
                message.Return = XmlHelper.XmlDocumentToString(doc);
            }
            catch (MESJobException ex)
            {
                res = XmlHelper.SetNGReturn(res, ex.ErrorCode.ToString(), ex.Message);
                message.Return = res;
            }

            if (!string.IsNullOrEmpty(message.Return))
            {
                message.Status = (int)EnumMesMsgStatus.WcsExcuted;
            }
            else
            {
                _logger.AddSystemErrorLog($"MesMsgParser->GetInventoryPalletDataRequest:处理时发生异常");
            }
        }


        private readonly IMesCommunicateService _mesCommunicateService;
        private readonly ILocationService _locationService;
        private readonly IPconBaseService _pconService;
        private readonly IBaseSrmTaskService _srmService;
        private readonly AutomaticStorageInfo _asrs;
        public MesMsgParser_GetInventoryPalletDataRequest(ILoggerService loggerService, WcsDbContext wcsDbContext, IMapper mapper, IMesCommunicateService mesCommunicateService, ILocationService locationService,
            IPconBaseService pconService, IBaseSrmTaskService srmService, AutomaticStorageInfo asrs) : base(loggerService, wcsDbContext, mapper)
        {
            _pconService = pconService;
            _srmService = srmService;
            _mesCommunicateService = mesCommunicateService;
            _locationService = locationService;
            _asrs = asrs;
        }

        public override string EventName => "GETINVENTORYPALLETDATAREQUEST";
    }
}
